package com.youbug.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youbug.Application;
import com.youbug.common.constant.MenuConstant;
import com.youbug.common.vo.CommonTreeVo;
import com.youbug.system.entity.Menu;
import com.youbug.system.entity.RoleMenu;
import com.youbug.system.mapper.MenuMapper;
import com.youbug.system.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.system.service.IRoleMenuService;
import com.youbug.common.util.MenuUtils;
import com.youbug.system.vo.MenuVo;
import com.youbug.system.vo.MenusForRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author apu
 * @since 2022-12-08
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
    @Autowired
    private IRoleMenuService roleMenuService;

    @Autowired
    private IMenuService menuService;

    @Override
    public List<Menu> getMenus(MenuVo menuVo) {

        QueryWrapper<Menu> wrapper = new QueryWrapper<>();

        wrapper.in("system_name", Application.getSystemNameList());

        List<Menu> menuList = this.list(wrapper);

        List<Menu> menus = MenuUtils.makeMenuTree(menuList, 0L);

        return menus;
    }

    @Override
    public List<CommonTreeVo> getParentMenus(MenuVo menuVo) {

        QueryWrapper<Menu> wrapper = new QueryWrapper<>();

        wrapper.ne("node_type", MenuConstant.BTN);

        wrapper.in("system_name", Application.getSystemNameList());

        List<Menu> menuList = this.list(wrapper);

        List<Menu> menus = MenuUtils.makeMenuTree(menuList, 0L);

        return  transToCommonTree(menus);
    }

    private List<CommonTreeVo> transToCommonTree(List<Menu> menus) {
        List<CommonTreeVo> treeVos = new ArrayList<>(menus.size());
        for (Menu menu : menus){
            List<Menu> subMenus = menu.getChildren();
            CommonTreeVo treeVo = new CommonTreeVo();
            treeVo.setLabel(menu.getName());
            treeVo.setValue(String.valueOf(menu.getId()));
            treeVo.setLevel(menu.getLevel());
            treeVo.setParentFullId(menu.getParentFullId());
            treeVo.setChildren(transToCommonTree(subMenus));
            treeVos.add(treeVo);
        }
        return treeVos;
    }

    @Override
    public List<Long> getMenusForRole(Long roleId) {

        List<RoleMenu> menus = roleMenuService.list(new QueryWrapper<RoleMenu>().eq("role_id", roleId));

        List<Long> menuIds = menus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());

        if(CollectionUtils.isEmpty(menuIds)){return  new ArrayList<>(0);}

        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<Menu>().in("id", menuIds);

        menuQueryWrapper.in("system_name", Application.getSystemNameList());

        List<Menu> list = menuService.list(menuQueryWrapper);

        return list.stream().map(Menu::getId).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Boolean saveMenusForRole(MenusForRoleVo menusForRoleVo) {

        roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("role_id",menusForRoleVo.getRoleId()));

        List<Menu> menus = menusForRoleVo.getMenus();

        Long roleId = menusForRoleVo.getRoleId();

        List<RoleMenu> roleMenus = new ArrayList<>();

        boolean b = false;

        if(!CollectionUtils.isEmpty(menus)){
            menus.forEach(m->{
                if(!"0|".equals(m.getParentFullId())){// 不可以仅仅保存一级菜单
                    roleMenus.add(new RoleMenu(roleId, m.getId(),m.getParentFullId()+m.getId()));
                }
             }
            );
            b = roleMenuService.saveBatch(roleMenus);
        }
        return b;
    }

    @Override
    public List<Menu> getMenusWithLevel(Object o) {

        QueryWrapper<Menu> wrapper = new QueryWrapper<>();

        wrapper.in("system_name", Application.getSystemNameList());

        List<Menu> menuList = this.list(wrapper);

        List<Menu> collect = menuList.stream().peek(menu -> menu.setName(menu.getName())).collect(Collectors.toList());

        List<Menu> menus = MenuUtils.makeMenuTree(collect, 0L);

        return menus;
    }
}
